/**
 * 
 */
package com.gragra.structures.generators;

import java.util.HashSet;
import java.util.Set;

/**
 * This class extends the split on whitespace approach by also adding the splitting of of leading and trailing punctuation
 * @author Christoph Teichmann
 * created Nov 13, 2012 12:22:57 AM
 * @version 0.1
 */
public class SplitOnWhiteSpaceSplitOfSurroundingPunctuation extends
		SplitOnWhiteSpaceCodeToIntegerGenerator
{
	/* (non-Javadoc)
	 * @see com.gragra.structures.Generators.SplitOnWhiteSpaceCodeToIntegerGenerator#process(java.lang.String)
	 */
	@Override
	protected String process(String input)
	{
		StringBuilder result = new StringBuilder();
		int length = input.length();
		boolean lastWhite = true;
		for(int i=0;i<length;++i)
		{
			char c = input.charAt(i);
			if(Character.isWhitespace(c))
			{
				result.append(c);
				lastWhite = true;
				continue;
			}
			if(splitOf.contains(c) && lastWhite)
			{
				result.append(c);
				result.append(' ');
				continue;
			}
			if(followedByWhite(i+1,input,length) && splitOf.contains(c))
			{
				result.append(' ');
				result.append(c);
				continue;
			}
			result.append(c);
			lastWhite = false;
		}
		return result.toString();
	}
	
	/**
	 * returns true if all the characters between pos and the next whitespace are
	 * punctuation, last argument is length of input, so it does not have to be looked
	 * up all the time
	 * @param pos
	 * @param input
	 * @param length 
	 * @return
	 */
	private boolean followedByWhite(int pos, String input, int length)
	{
		for(int i=pos;i<length;++i)
		{
			char c = input.charAt(i);
			if(Character.isWhitespace(c))
			{return true;}
			if(splitOf.contains(c))
			{continue;}
			else
			{return false;}
		}
		return true;
	}
	/**
	 * the set of characters that are considered punctuation
	 */
	private final static Set<Character> splitOf;
	static{
		splitOf = new HashSet<Character>();
		splitOf.add('_');
		splitOf.add('-');
		splitOf.add('.');
		splitOf.add(':');
		splitOf.add(',');
		splitOf.add(';');
		splitOf.add('/');
		splitOf.add('\"');
		splitOf.add('\'');
		splitOf.add('\'');
		splitOf.add('`');
		splitOf.add('?');
		splitOf.add('!');
		splitOf.add('(');
		splitOf.add(')');
	}
}